#ifndef __ADVENTURE_MAP_H__
#define __ADVENTURE_MAP_H__

/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 adventure_map.h

	$Header: /heroes4/adventure_map.h $

	$NoKeywords: $

 ************************************************************************/

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <bitset>
#include <list>
#include <map>

#include "abstract_adventure_map.h"
#include "adv_ferry_vector.h"
#include "adv_magi_eye.h"
#include "adv_obelisk.h"
#include "adv_object_type.h"
#include "adv_subterranean_gate_vector.h"
#include "adv_teleporter_exit_vector.h"
#include "adv_whirlpool_vector.h"
#include "adventure_events_base.h"
#include "adventure_events_playback.h"
#include "adventure_map_ptr.h"
#include "adventure_map_window_ptr.h"
#include "adventure_object_memory_cache.h"
#include "adventure_object_ptr.h"
#include "adv_ferry_vector.h"
#include "adv_magi_eye.h"
#include "adv_obelisk.h"
#include "adv_object_type.h"
#include "adv_subterranean_gate_vector.h"
#include "adv_teleporter_exit_vector.h"
#include "adv_whirlpool_vector.h"
#include "adventure_events_base.h"
#include "adventure_events_playback.h"
#include "adventure_events_spells_effect.h"
#include "adventure_map_ptr.h"
#include "adventure_map_window_ptr.h"
#include "adventure_object_memory_cache.h"
#include "adventure_object_ptr.h"
#include "army_list.h"
#include "army_ptr.h"
#include "artifact_ai_importance_map.h"
#include "artifact_set.h"
#include "artifact_type.h"
#include "campaign_file_ref.h"
#include "caravan_set.h"
#include "carryover_data_ptr.h"
#include "counted_ptr.h"
#include "default_heroes.h"
#include "difficulty_level.h"
#include "gateway_vector.h"
#include "global_event_list.h"
#include "isometric_map.h"
#include "map_point_list.h"
#include "map_size.h"
#include "minimum_maximum.h"
#include "memory_buffer.h"
#include "obelisk_data.h"
#include "obelisk_marker.h"
#include "override_input_handler.h"
#include "ownable_garrisonable_adv_object_list.h"
#include "path_search_type.h"
#include "player_color.h"
#include "player_list.h"
#include "player_setup.h"
#include "respawn_point.h"
#include "saved_game_header.h"
#include "scenario_cut_scene_info.h"
#include "shroud_transition_map.h"
#include "skill_set.h"
#include "spell_ai_importance_map.h"
#include "spell_set.h"
#include "string_insensitive_compare.h"
#include "town_ptr.h"
#include "uncopyable.h"

class  t_actor;
class  t_adv_shipyard;
class  t_adventure_ai;
class  t_adventure_path;
class  t_adventure_path_finder;
enum   t_ai_importance;
class  t_artifact;
enum   t_difficulty;
enum   t_direction;
class  t_hero;
class  t_adv_magi_eye;
class  t_map_header;
struct t_map_rect;
struct t_map_rect_2d;
class  t_mini_map_window;
class  t_owned_adv_object;
class  t_player;
enum   t_player_color;
class  t_saved_combat;
enum   t_town_type;
enum   t_adv_actor_action_id;


typedef std::map<t_adventure_global_id, t_adventure_object_ptr>	t_adventure_global_id_map;

typedef std::list<t_obelisk_marker>			t_obelisk_marker_list;
typedef t_owned_ptr<t_override_input>		t_override_input_ptr;

typedef t_counted_ptr<t_adv_shipyard>		t_shipyard_ptr;
typedef std::list<t_shipyard_ptr>			t_shipyard_list;

enum t_increase_visibility_type
{
	k_increase_visibility_both, 
	k_increase_visibility_land_only, 
	k_increase_visibility_water_only
};


// -------------------------------------------------------------------
// adventure tile. 
// -------------------------------------------------------------------
class t_adventure_tile : public t_abstract_adventure_tile
{
public:
	t_adventure_tile();

	void								add_trigger( int object_id, bool on_bridge );
	void								remove_trigger( int object_id, bool on_bridge );
	const std::vector<int>&	get_triggers( bool on_bridge ) const;
	bool								ai_can_build_ship() const;
	int									ai_get_shipyard_id() const;
	void								ai_set_can_build_ship( bool buildable, int shipyard_id );
	bool								blocks_army( t_creature_array	const& army, t_adventure_map const&	map,
											bool on_bridge, t_path_search_type path_type = k_path_search_standard) const;
	void								change_bridge_count( int change );
	void								change_edge_block_count( bool right_edge, bool on_bridge, int change );
	void								change_ramp_count( int change );
	void								change_ramp_open_count( bool right_edge, int change );
	void								decrement_block();
	void								decrement_left_trigger( bool on_bridge );
	void								decrement_right_trigger( bool on_bridge );
	bool								has_bridge() const;
	bool								has_ramp() const;
	void								increment_block();
	void								increment_left_trigger( bool on_bridge );
	void								increment_right_trigger( bool on_bridge );
	bool								is_blocked( bool on_bridge ) const;
	bool								is_edge_blocked( bool right_edge, bool on_bridge ) const;
	bool								is_dangerous( bool on_bridge ) const;
	bool								is_ramp_open( bool right_edge ) const;
	bool								is_trigger( bool on_bridge ) const;
	bool								left_is_trigger( bool on_bridge ) const;
	bool								right_is_trigger( bool on_bridge ) const;
	void								set_dangerous( bool on_bridge, bool arg );	

protected:
	bool					m_ai_can_build_ship;
	bool					m_in_danger[2]; // true if displayed path shows danger
	int						m_ai_shipyard_id;
	t_uint8					m_blocking_objects; // true if tile is blocked ( !on_bridge )
	t_uint8					m_bridge_count;
	t_uint8					m_edge_blocked[2][2];
	t_uint8					m_left_trigger_edges[2];
	t_uint8					m_ramp_count;
	t_uint8					m_ramp_open[2]; // Can transition bridge -> lower or visa versa
	t_uint8					m_right_trigger_edges[2];
	std::vector<int>		m_trigger_objects[2];
};

inline bool t_adventure_tile::is_dangerous( bool on_bridge ) const
{
	return m_in_danger[on_bridge];
}

inline void t_adventure_tile::set_dangerous( bool on_bridge, bool arg )
{
	m_in_danger[on_bridge] = arg;
}
// -------------------------------------------------------------------
// adventure tile vertex
// -------------------------------------------------------------------
class t_adventure_tile_vertex : public t_abstract_adventure_tile_vertex
{
public:
	t_adventure_tile_vertex();

	int  get_bridge_height() const;
	void set_bridge_height( int arg );
protected:
	t_uint16 m_bridge_height;
};

inline t_adventure_tile_vertex::t_adventure_tile_vertex()
{
	m_bridge_height = 0;
}

inline int t_adventure_tile_vertex::get_bridge_height() const
{
	return m_bridge_height;
}

inline void t_adventure_tile_vertex::set_bridge_height( int arg )
{
	m_bridge_height = arg;
}

// -------------------------------------------------------------------
// inlines for adventure tile. 
// -------------------------------------------------------------------
inline t_adventure_tile::t_adventure_tile()
{
	m_blocking_objects = 0;
 	m_bridge_count = 0;
	m_in_danger[0] = false;
	m_in_danger[1] = false;
	m_left_trigger_edges[0] = 0;
	m_left_trigger_edges[1] = 0;
	m_ramp_count = 0;
	m_right_trigger_edges[0] = 0;
	m_right_trigger_edges[1] = 0;
	m_ai_can_build_ship = false;
	m_ai_shipyard_id = -1;
	
	memset( m_edge_blocked, 0, sizeof( m_edge_blocked ));
	memset( m_ramp_open, 0, sizeof( m_ramp_open ) );
}

inline bool t_adventure_tile::ai_can_build_ship() const
{
	return m_ai_can_build_ship;
}

inline int t_adventure_tile::ai_get_shipyard_id() const
{
	return m_ai_shipyard_id;
}

inline void	t_adventure_tile::ai_set_can_build_ship( bool buildable, int shipyard_id )
{
	m_ai_can_build_ship = buildable;
	m_ai_shipyard_id = shipyard_id;
}

inline void t_adventure_tile::change_bridge_count( int change )
{
	m_bridge_count += change;
}

inline void t_adventure_tile::change_edge_block_count( bool right_edge, bool on_bridge, int change )
{
	m_edge_blocked[right_edge][on_bridge] += change;
}

inline void t_adventure_tile::change_ramp_count( int change )
{
	m_ramp_count += change;
}

inline void	t_adventure_tile::change_ramp_open_count( bool right_edge, int change )
{
	m_ramp_open[ right_edge ] += change;
}

inline bool t_adventure_tile::has_bridge() const
{
	return m_bridge_count > 0;
}

inline bool t_adventure_tile::has_ramp() const
{
	return m_ramp_count > 0;
}

inline bool t_adventure_tile::is_blocked( bool on_bridge ) const
{
	// Bridges are NEVER permenantly blocked; only armies are on bridges
	if ( on_bridge )
		return !has_bridge();
	else
		return m_blocking_objects > 0;
}

inline bool t_adventure_tile::is_edge_blocked( bool right_edge, bool on_bridge ) const
{
	return m_edge_blocked[right_edge][on_bridge] > 0;
}

inline bool t_adventure_tile::is_ramp_open( bool right_edge ) const
{
	return m_ramp_open[ right_edge ] > 0;
}

inline bool t_adventure_tile::is_trigger( bool on_bridge ) const
{
	return m_trigger_objects[on_bridge].size() > 0;
}

inline bool t_adventure_tile::left_is_trigger( bool on_bridge ) const
{
	return m_left_trigger_edges[on_bridge] > 0;
}

inline bool t_adventure_tile::right_is_trigger( bool on_bridge ) const
{
	return m_right_trigger_edges[on_bridge] > 0;
}

inline void t_adventure_tile::add_trigger( int object_id, bool on_bridge )
{
	m_trigger_objects[on_bridge].push_back( object_id );
}

inline void t_adventure_tile::remove_trigger( int object_id, bool on_bridge )
{
	std::vector<int>::iterator index = std::find( m_trigger_objects[on_bridge].begin(),
		                                          m_trigger_objects[on_bridge].end(), object_id );
	m_trigger_objects[on_bridge].erase( index );
}

inline const std::vector<int>&	t_adventure_tile::get_triggers( bool on_bridge ) const
{
	return m_trigger_objects[on_bridge];
}

inline void t_adventure_tile::decrement_block()
{
	m_blocking_objects--;
}

inline void t_adventure_tile::decrement_left_trigger( bool on_bridge )
{
	m_left_trigger_edges[on_bridge]--;
}

inline void t_adventure_tile::decrement_right_trigger( bool on_bridge )
{
	m_right_trigger_edges[on_bridge]--;
}

inline void t_adventure_tile::increment_block()
{
	m_blocking_objects++;
}
	
inline void t_adventure_tile::increment_left_trigger( bool on_bridge )
{
	m_left_trigger_edges[on_bridge]++;
}

inline void t_adventure_tile::increment_right_trigger( bool on_bridge )
{
	m_right_trigger_edges[on_bridge]++;
}

// -------------------------------------------------------------------
// adventure map class. 
// -------------------------------------------------------------------

class t_adventure_map : public t_abstract_adventure_map, public t_counted_object, private t_uncopyable
{
public:
	class t_town_list : public std::list< t_town_ptr > {};
    
	t_adventure_map();
	t_adventure_map( int size, int levels, int seed, t_difficulty player_difficulty, 
					 int turn_duration, bool guards_move );
	virtual ~t_adventure_map();

	bool						activate_trigger( t_army* army, t_adv_map_point const& point,
								                  t_direction direction,
								                  t_adventure_frame* frame );
	void						adventure_event_finished( t_adventure_event_base * event);
	void						add( t_army* army );
	void						add( t_ownable_garrisonable_adv_object* garrison );
	void						add( t_town* town );
	void						add_caravan( t_caravan_ptr caravan );
	void						add_defeated_hero( t_hero* hero );
	void						add_deletion_marker( std::string const& name, t_adv_map_point const& point );
	void						add_free_materials();
    void						add_ferry( t_adv_ferry_const_ptr const & ferry );
    void						add_gateway( t_gateway_ptr const & gateway  );
    void						add_obelisk( t_adv_obelisk& obelisk );
    void						add_obelisk_marker( t_obelisk_color marker_color, t_obelisk_marker const & marker );
    void						add_player( t_player_ptr new_player_ptr );
    void						add_magi_eye( t_adv_magi_eye& magi_eye );
	void						add_mapped_name( std::string const& name, t_hero* hero );
	void						add_mapped_name( std::string const& name, t_town* town );
	void						add_respawn_point( t_respawn_point const & point );
	void						add_shipyard( t_adv_shipyard& shipyard );
    void						add_subterranean_gate( t_adv_subterranean_gate_ptr gate );
    void						add_teleporter_exit( t_adv_teleporter_exit_ptr const & exit );
    void						add_to_total_income ( int amount );
    void						add_whirlpool( t_adv_whirlpool_ptr const & whirlpool );
	void						assign_global_id( t_adventure_object * object, t_adventure_global_id const & new_global_id );
	void						attach( t_adventure_map_window* map_window );
	void						attach_event_to_adventure_map ( t_adventure_object * object, t_adventure_event_base * new_event );
	void						attach_event_to_state_cache( t_adventure_object * object, t_adventure_event_base * new_event );
	t_carryover_data_ptr		build_carry_out_data();
	void						cache_adventure_object_state ( t_adventure_object * object );
	bool						can_place_new_boat( t_adv_map_point const& center, bool ignore_removable ) const;
	void						clear_path();
	void						clear_saved_combat();
	void						clear_selection();
	bool						corners_block( t_adv_map_point const&	point,
											   t_adv_map_point const&	new_point,
											   t_direction				direction ) const;
	virtual	int					compute_height( t_abstract_adv_object const& object,
												 t_level_map_point_2d const&  pos ) const;
	t_hero*						create_hero( t_default_hero const& data, 
								             t_town_type alignment ) const;
	t_adventure_map_ptr			create_replay_map( t_progress_handler*	handler );
	void						decrement_victory_timer();
	void						display_path( t_adventure_path const& path,
								              int movement );
	void						display_selection( t_adventure_object* object );
	void						event_playback_finish();
	void						free_hero_usage( int biography_id, int portrait_id );
	t_adventure_object *		get_adventure_object_with_gid ( t_adventure_global_id const & global_id );
	t_adventure_object &		get_adv_object( t_object_id id );
	t_adventure_object const &	get_adv_object( t_object_id id ) const;
	t_adventure_tile const&		get_adv_tile( t_level_map_point_2d const& point ) const;
	t_adventure_tile&			get_adv_tile( t_level_map_point_2d const& point );
	t_adventure_ai const &		get_ai() const;
	t_adventure_ai &			get_ai();
	t_ai_importance				get_ai_importance_for_artifact( t_artifact const & artifact ) const;
	t_ai_importance				get_ai_importance_for_artifact( t_artifact_type type, t_spell spell ) const;
	t_artifact_set const &		get_allowed_artifacts() const;
	t_bool_array const &		get_allowed_heroes() const;
	t_skill_set const &			get_allowed_skills() const;
	t_spell_set const &			get_allowed_spells() const;
	t_army_list::iterator		get_armies_begin();
	t_army_list::iterator		get_armies_end();
	bool						get_boolean_script_variable( std::string const& name, bool& value) const;
	t_adventure_object_cache_manager*		get_cache_manager();
	t_caravan_set &							get_caravans();
	t_caravan_set const &					get_caravans() const;
	t_artifact_set const &					get_carry_in_artifacts() const;
	t_carryover_data *						get_carry_in_data();
	t_artifact_set const &					get_carry_out_artifacts() const;
	t_carryover_data const *				get_carry_out_data() const;
	t_carryover_data *						get_carry_out_data();
	t_adventure_object const &				get_const_adv_object( t_object_id id ) const;
	t_player&								get_current_player();
	t_player const&							get_current_player() const;
	int										get_current_player_number() const;
	int										get_day() const;
	t_scenario_cut_scene_info const&		get_epilogue_info() const;
	t_adventure_event_list const &			get_events_list();
	t_adv_ferry_const_vector				get_ferries() const;
    t_adv_ferry_const_vector				get_ferries_in_group( t_adv_ferry_const_ptr ferry ) const;
	t_campaign_file_ref const &				get_file_ref() const;
	virtual t_object_id						get_first_object_id() const;
	t_saved_game_header const &				get_event_header( );
    t_gateway_vector						get_gateways( int gateway_type );
    t_gateway_const_vector					get_gateways( int gateway_type ) const;
	t_default_hero							get_generic_hero( int portrait_id ) const;
	virtual t_object_id						get_last_object_id() const;
	t_player&								get_player() const;
	int										get_player_number() const;
	std::string const &				 		get_loss_condition_string( t_player_color color ) const;
	t_adv_magi_eye_list const &				get_magi_eyes() const;
	int										get_map_number() const;
	t_adventure_map_window*					get_map_window() const;
	t_map_size								get_map_size_type() const;
	t_hero*									get_mapped_hero( std::string const& name );
	t_hero const*							get_mapped_hero( std::string const& name ) const;
	t_town*									get_mapped_town( std::string const& name );
	t_town const*							get_mapped_town( std::string const& name ) const;
	t_adventure_global_id					get_new_global_adventure_id( );
	int										get_new_single_use_id();
	t_creature_type							get_next_month_creature();
	virtual t_object_id						get_next_object_id( t_object_id id ) const;
	bool									get_numeric_script_variable( std::string const& name, int& value) const;
    t_obelisk_list							get_obelisk_list( int obelisk_type = -1 );
    t_level_map_point_2d					get_obelisk_artifact_position( t_obelisk_color obelisk_type ) const;
    bool                                    get_obelisk_completed( t_obelisk_color color) const;
	t_obelisk_marker_list const &			get_obelisk_marker_list( t_obelisk_color obelisk_type ) const;
    bool                                    get_obelisk_treasure_placed( t_obelisk_color color) const;
	t_obelisk_reward_list const &			get_obelisk_reward_list( t_obelisk_color obelisk_type ) const;
	virtual t_object &						get_object( t_object_id id );
	virtual t_object const &				get_object( t_object_id id ) const;
	t_adventure_object *					get_object_by_global_id( t_adventure_global_id id );
	t_adventure_object const *				get_object_by_global_id( t_adventure_global_id id ) const;
	virtual t_level_map_point_2d			get_object_pos( t_object_id id ) const;
	int										get_or_add_player_number( t_player_color color );
	t_ownable_garrisonable_adv_object_list::iterator	get_garrisons_begin();
	t_ownable_garrisonable_adv_object_list::iterator	get_garrisons_end();
	float									get_percent_explored( int team_num ) const;
	t_player&								get_player( int id ) const;
	t_player*								get_player( t_player_color color ) const;
	t_difficulty							get_player_difficulty() const;
	t_player_list const&					get_players() const;
	int										get_player_count() const;
	int										get_player_number( t_player_color color ) const;
	virtual t_object_id						get_prev_object_id( t_object_id id ) const;
	t_creature_type							get_previous_month_creature();
	t_scenario_cut_scene_info const &		get_prologue_info() const;
	t_artifact_type							get_random_artifact( t_artifact_level level );
	t_artifact_type							get_random_artifact( t_artifact_type const* array,
											                     int					 count );
	std::string								get_random_name( t_qualified_adv_object_type const & type );
	t_spell									get_random_parchment( int level );
	t_artifact_type							get_random_potion( );
    int										get_required_obelisks( t_obelisk_color obelisk_type ) const;
	t_saved_combat*							get_saved_combat();
	t_shipyard_list&						get_shipyards();
	virtual t_shroud_transition_map *		get_shroud_transition_map_ptr( int team_num );
	virtual t_shroud_transition_map const *	get_shroud_transition_map_ptr( int team_num ) const;
	bool									get_standard_victory_condition() const;
    t_adv_subterranean_gate_vector const &	get_subterranean_gates( );
	int										get_team_lighthouse_count( int player_number ) const;
	t_adv_teleporter_exit_vector			get_teleporter_exits( int exit_type );
	t_adv_teleporter_exit_const_vector		get_teleporter_exits( int exit_type ) const;
	virtual const t_tile&					get_tile( t_level_map_point_2d point ) const;
	virtual t_tile&							get_tile( t_level_map_point_2d point );
	virtual const t_tile_vertex&			get_tile_vertex( t_level_map_point_2d point ) const;
	virtual t_tile_vertex&					get_tile_vertex( t_level_map_point_2d point );
	virtual t_const_tile_vertex_quad		get_tile_vertex_quad( t_level_map_point_2d point ) const;
	virtual t_tile_vertex_quad				get_tile_vertex_quad( t_level_map_point_2d point );
	int										get_total_income() const;
	int										get_town_count() const;
	t_town_list::const_iterator				get_towns_begin() const;
	t_town_list::const_iterator				get_towns_end() const;
	t_town_list::iterator					get_towns_begin();
	t_town_list::iterator					get_towns_end();

	t_adventure_object*						get_trigger_object( t_adv_map_point const& point, 
																 t_creature_array const* army ) const;
	t_adventure_object*						get_trigger_object( t_adv_map_point const& point, 
											                    t_direction direction,
											                    t_creature_array const* army = 0) const;
    int                                     get_turn_duration_index() const;
	std::vector<t_default_hero>				get_unused_heroes( t_hero_class hero_class, bool male ) const;
	std::string const &				 		get_victory_condition_string( t_player_color color ) const;
	int										get_victory_timer() const;
	int										get_winning_team() const;
    t_adv_whirlpool_vector					get_whirlpools();
    t_adv_whirlpool_const_vector			get_whirlpools() const;
	bool									guards_can_move() const;
	bool									has_empty_boat( t_player const& player );
	bool									has_human_players( int team ) const;
	void									increase_visibility( int							team_num,
																 t_level_map_point_2d const &	location,
																 t_map_point_2d const &			size,
																 int							radius,
																 t_tile_visibility				new_visibility,
																 t_visibility_set &				changed_tile_points,
																 t_increase_visibility_type		visibility_type = k_increase_visibility_both );
	void									increase_visibility( int							team_num,
																 t_level_map_point_2d const &	location,
																 t_map_point_2d const &			size,
																 int							scouting_range,
																 int							attack_range,
																 t_skill_mastery				new_scouting,
																 t_visibility_set &				changed_tile_points );
	void									increase_visibility( int							team_num,
																t_level_map_point_2d const &	location,
											  					t_map_point_2d const &		size,
											  					int							scouting_range,
											  					int							attack_range,
											  					t_tile_visibility				new_visibility,
											  					t_skill_mastery				new_scouting,
											  					t_visibility_set &			changed_tile_points,
											  					t_increase_visibility_type	visibility_type = k_increase_visibility_both );
	void									initialize_players( t_difficulty );
	void									increment_spell_count( t_spell );
	void									increment_event_tick();
	bool									is_blocked( t_adv_map_point const&       point ) const;
	bool									is_blocked( t_adv_map_point const&       point,
														t_direction					 direction ) const;
	bool									is_cheater() const;
	virtual bool							is_floating( t_object_id id ) const;
	bool									is_hero_portrait_used( int portrait_id ) const;
	bool									is_hotseat() const;
	bool									is_land( t_level_map_point_2d const& point ) const;
	bool									is_game_over();
	bool									is_multi_scenario() const;
	bool									is_ocean( t_level_map_point_2d const& point ) const;
	// check if an army can be placed in a tile
	bool									is_open( t_adv_map_point const&  point, 
													 t_creature_array const& army ) const;
	bool									is_permanently_blocked( t_adv_map_point const& point ) const;
	bool									is_ramp_open( t_adv_map_point const & point, t_direction direction ) const;
	bool									is_river( t_level_map_point_2d const& point ) const;
	bool									is_trigger( t_adv_map_point point );
    bool									occupies_contiguous_water( t_level_map_point_2d const &origin,
																	   t_map_point_2d const &footprint_size,
																	   t_level_map_point_2d const &target_point,
																	   t_map_point_2d const &target_footprint_size,
																	   char *map_grid,
																	   int const &map_size );
	void									on_visibility_changed( int					team_num,
																   int					level,
																   t_visibility_set &	changed_tile_points );
	void									memory_cache_refrence_remove ( t_adventure_global_id	object_gid );
	void									post_trigger( t_army* army, t_adventure_object* object,
														  t_adventure_frame* frame );
	void									process_continuous_events( t_adventure_frame* frame );
	void									process_day_end( t_adventure_frame* frame );
	void									process_placed_events(std::string const& name, t_army& army, t_adventure_object_ptr removal_object );
	void									process_timed_events(t_adventure_frame* frame);
	void									process_triggerable_events(std::string const& string, t_adventure_frame* frame);
	bool									read( std::streambuf& buffer, t_progress_handler* handler );
	bool									read_from_map( std::streambuf&				buffer, 
														   t_campaign_file_ref const &	file_ref,
														   int							map_num,
														   bool							multi_scenario,
											               t_progress_handler*			handler,
														   t_player_setup const*		player_setup,
														   t_difficulty					player_difficulty,
                                                           int							turn_duration_index,
														   t_carryover_data_ptr			carry_in_data,
														   bool							guards_move );
	bool									read_and_place_adventure_object( std::streambuf& buffer, t_saved_game_header const & header,
																										t_adventure_object_ptr & object );
	bool									record_adv_spell_effect( t_army* target, k_spell_effects_event_id spell_id,
																			bool run_modal );
	void									record_hero_usage( int biography_id, int portrait_id );
	bool									record_mover_event( t_army* army,  t_adventure_path const & path , bool limit_move, t_adv_map_point orig_point );
	bool		 							record_look_trigger_event( t_actor* adv_object , t_direction dir );
	bool		 							record_placement_event( t_adventure_object* object, t_level_map_point_2d point );
	bool		 							record_remove_event( t_adventure_object* object );
	bool									record_replay_shroud();
	bool		 							record_set_action_event( t_actor* army,  t_adv_actor_action_id action_state );
	bool		 							record_set_owner_event( t_army * object, int owner );
	bool		 							record_set_owner_event( t_owned_adv_object* object, int owner );
	bool		 							record_teleport_event ( t_adventure_object* object, t_adv_map_point point_a, 
																t_level_map_point_2d point_b );
	bool		 							record_update_event ( t_adventure_object* object );
	bool		 							record_visiblity_event ( t_army* army, t_adv_map_point const& point, 
															t_direction direction, t_adventure_object* source );
	void									remove( t_army* army );
	void									remove( t_ownable_garrisonable_adv_object* garrison );
	void									remove( t_town* town );
	void									remove_caravan( t_caravan_ptr caravan );
    void									remove_ferry( t_adv_ferry_const_ptr const & ferry );
	void									remove_gateway( t_gateway_ptr const & gateway );
	void									remove_object( t_adventure_object* object );
	void									remove_object( t_adventure_global_id const & object_gid );
	void									remove_by_deletion_marker( std::string const& name );
	void									remove_shipyard( t_adv_shipyard& shipyard );
	void									remove_subterranean_gate( t_adv_subterranean_gate_ptr const & gate );
    void									remove_teleporter_exit( t_adv_teleporter_exit_ptr const & exit );
	void									remove_visibility( int							team_num,
															   t_level_map_point_2d const &	location,
															   t_map_point_2d const &		size,
															   int							radius,
															   t_visibility_set &			changed_tile_points );
    void									remove_whirlpool( t_adv_whirlpool_ptr const & whirlpool );
	void									reset_danger();
	void									resume_turn( t_adventure_frame* frame );
	void									reuse( t_artifact_type artifact );
	void									rollback_replay_events( int select_team );
	t_spell_set								select_spells( t_spell_set const& spells ) const;
	void									set_boolean_script_variable( std::string const& name, bool value );
	void									set_cheater( bool arg = true );
	void									set_current_player( int arg );
	void									set_day( int arg );
	void									set_event_header( t_saved_game_header const & event_header );
	void									set_game_over( bool over );
	void									set_is_replay_map( bool arg );
	void									set_player( int arg );
	void							 		set_loss_condition_string( t_player_color color, std::string const & loss_condition );
	void									set_next_player( t_adventure_frame* frame );
	void									set_numeric_script_variable( std::string const& name, int value );
    void									set_obelisk_artifact_position(  t_obelisk_color obelisk_type, t_level_map_point_2d const& point);
    void                                    set_obelisk_completed( t_obelisk_color color, bool completed = true );
    void                                    set_obelisk_treasure_placed( t_obelisk_color color, bool placed = true );
	void									set_player_difficulty( t_difficulty difficulty );
	void									set_standard_victory_condition( bool condition );
	void							 		set_victory_condition_string( t_player_color color, std::string const & victory_condition );
	void									set_winning_team( int team );
	void									start_event_record();
	void									start_event_playback();
	void									stop_event_playback();
	void									stop_event_record();
	void									store_map_score( int score, int days );
	void									update_event_buffer( int player_id );
	void									use_artifact( t_artifact_type artifact );
	bool									use_replay_shroud();
	int										which_team_owns_all_towns() const;
	void									write( std::streambuf& buffer, t_progress_handler* handler,
												   t_saved_combat* saved_combat = 0 );
	bool									write_adventure_object( std::streambuf& buffer, t_saved_game_header const & header, 
																t_adventure_object*  object ) const;

	t_adventure_tile const& operator[]( t_level_map_point_2d point ) const;

protected:
	friend class t_adventure_object;

	// Used internally by calculate_ferry_groups() and its helpers
	typedef std::map< t_adv_ferry const *, t_level_map_point_2d_list > t_ferry_points_map;
	typedef std::multimap< t_level_map_point_2d, t_adv_ferry const * > t_point_ferry_map;

	void			begin_neutral_turn();
	void			calculate_ferry_groups() const;
	void			calculate_ferry_groups_add_ferry( t_adv_ferry const * ferry,
													   t_level_map_point_2d_list & open_list,
													   t_bool_array & listed_points,
													   int group_id,
												  	   t_adv_ferry_const_vector & group_vector,
													   t_ferry_points_map const & ferry_points_map ) const;
	void			calculate_ferry_groups_push( t_level_map_point_2d const & point,
												  t_level_map_point_2d_list & open_list,
												  t_bool_array & listed_points ) const;
	void			choose_next_month_creature();
	void			create_shroud_transition_maps();
	void			do_new_month();
	void			float_object( int id );
	int				get_next_player() const;
	void			initialize();
	void			initialize( int size, int levels, int seed, t_difficulty player_difficulty, int turn_duration_index );
	void			mark_danger();
	t_object_id		place_object( t_adventure_object* object, t_adv_map_point point );
	void			process_new_day();
	bool		 read_ai_importance_maps( std::streambuf & stream, int version ); 
	bool		 read_ai_importance_maps_from_map( std::streambuf & stream, t_map_header const& header ); 
	bool		 read_allowed_artifacts( std::streambuf & stream, int version );
	bool		 read_allowed_artifacts_from_map( std::streambuf & stream, t_map_header const& header );
	bool		 read_allowed_heroes( std::streambuf & stream, int version );
	bool		 read_allowed_heroes_from_map( std::streambuf & stream, t_map_header const& header );
	bool		 read_allowed_skills( std::streambuf & stream, int version );
	bool		 read_allowed_skills_from_map( std::streambuf & stream, t_map_header const& header );
	bool		 read_allowed_spells( std::streambuf & stream, int version );
	bool		 read_allowed_spells_from_map( std::streambuf & stream, t_map_header const& header );
	bool		 read_carryover_artifacts( std::streambuf & stream, int version );
	bool		 read_carryover_artifacts_from_map( std::streambuf & stream, t_map_header const& header );
	bool		 read_carryover_data( std::streambuf & stream, int version );
	bool		 read_cut_scene_info_from_map( std::streambuf & stream, t_map_header const& header );
	bool		 read_defeated_heroes( std::streambuf & stream, int version );
	void         read_heights( std::streambuf& buffer, t_progress_handler* handler );
	bool		 read_caravans( std::streambuf & buffer, int version );
	bool         read_continuous_events_from_map( std::streambuf& stream,
		                                          t_map_header const& header );
	bool		 read_cut_scene_info( std::streambuf & stream, int version );
	bool		 read_deletion_marker_map( std::streambuf& stream, int version );
	bool		 read_events( std::streambuf& stream, int version );
	bool		 read_monthly_creatures( std::streambuf& stream, int version );
	bool		 read_obelisk_data( std::streambuf & stream, int version );
	bool		 read_obelisk_data_from_map( std::streambuf & stream, t_map_header const& header );
	bool         read_placed_events_from_map( std::streambuf& stream,
		                                      t_map_header const& header );
	bool		 read_player_data_body_from_map( std::streambuf& stream,
												 t_map_header const& header );
	bool		 read_replay_events( std::streambuf& stream , int version);
	bool		 read_replay_event_state_cache( std::streambuf& stream );
	bool		 read_script_variable_maps( std::streambuf& stream, int version );
	bool		 read_shroud_transition_maps( std::streambuf& stream, int version );
	bool		 read_terrain_map( std::streambuf& stream, int version );
	void         read_tile( std::streambuf& buffer,
		                    t_adventure_tile& tile,
							t_level_map_point_2d const& point,
							t_map_header const& header,
							t_progress_handler* handler );
	bool         read_timed_events_from_map( std::streambuf& stream,
									         t_map_header const& header );
	bool         read_triggerable_events_from_map( std::streambuf& stream,
												   t_map_header const& header );
	bool		 read_winloss_strings( std::streambuf & stream, int version );

	void		 rebuild_shroud_transitions();
	bool         set_players( t_map_header const & header,
							  t_player_setup const* player_setup );
	void         sink_object( int id );
	virtual void stamp_object( t_object_id id );
	void		 stamp_object_height( t_adventure_object const& object );
	virtual void unstamp_object( t_object_id id );

	bool		 write_ai_importance_maps( std::streambuf & stream ) const; 
	bool		 write_allowed_artifacts( std::streambuf & stream ) const;
	bool		 write_allowed_heroes( std::streambuf & stream ) const;
	bool		 write_allowed_skills( std::streambuf & stream ) const;
	bool		 write_allowed_spells( std::streambuf & stream ) const;
	bool		 write_caravans( std::streambuf & buffer ) const;
	bool		 write_carryover_artifacts( std::streambuf & stream ) const;
	bool		 write_carryover_data( std::streambuf & stream ) const;
	bool		 write_cut_scene_info( std::streambuf & stream ) const;
	bool		 write_defeated_heroes( std::streambuf & stream ) const;
	bool		 write_deletion_marker_map( std::streambuf& stream ) const;
	bool		 write_events( std::streambuf& stream ) const;	
	bool		 write_monthly_creatures( std::streambuf& stream ) const;
	bool		 write_obelisk_data( std::streambuf & stream ) const;
	bool		 write_replay_events( std::streambuf& stream ) const;
	bool		 write_replay_event_state_cache( std::streambuf& stream ) const;
	bool		 write_script_variable_maps( std::streambuf& stream ) const;
	bool		 write_shroud_transition_maps( std::streambuf& stream ) const;
	bool		 write_terrain_map( std::streambuf& stream ) const;
	bool		 write_winloss_strings( std::streambuf& stream ) const;

	struct t_object_node
	{
		t_adventure_object_ptr object;
		int                    next;
		int                    last;
	};

	typedef t_isometric_map<t_adventure_tile> t_terrain_map;
	typedef t_isometric_vertex_map<t_adventure_tile_vertex> t_vertex_map;
	typedef std::vector<t_object_node> t_object_node_list;
	typedef std::vector<t_adventure_object_ptr>	t_object_list;
	typedef std::list<t_adv_map_point> t_point_list;
	typedef std::map<std::string, int, t_string_insensitive_less> t_numeric_variable_map;
	typedef std::map<std::string, bool, t_string_insensitive_less> t_boolean_variable_map;
	typedef std::map<std::string, t_point_list, t_string_insensitive_less> t_deletion_marker_map;
	typedef std::map<std::string, t_town*, t_string_insensitive_less> t_town_name_map;
	typedef std::map<std::string, t_hero*, t_string_insensitive_less> t_hero_name_map;
	typedef t_owned_ptr< t_shroud_transition_map > t_shroud_transition_map_ptr;
	typedef std::list< t_respawn_point > t_respawn_point_list;
	typedef std::map< t_adv_ferry_const_ptr, int > t_ferry_group_id_map;
	typedef std::vector< t_adv_ferry_const_vector > t_ferry_group_vector;
	typedef std::vector< t_gateway_vector > t_gateway_vector_vector;
	typedef std::vector< t_adv_teleporter_exit_vector > t_teleporter_exit_vector_vector;
	typedef std::vector< t_bool_array > t_bool_vector_vector;
	typedef std::vector< t_counted_ptr< t_hero > > t_hero_list;

	typedef t_global_timed_event			t_timed_event;
	typedef t_global_timed_event_ptr		t_timed_event_ptr;
	typedef t_global_timed_event_list		t_timed_event_list;
	typedef t_global_triggerable_event		t_triggerable_event;
	typedef t_global_triggerable_event_ptr	t_triggerable_event_ptr;
	typedef t_global_triggerable_event_list	t_triggerable_event_list;
	typedef t_global_continuous_event		t_continuous_event;
	typedef t_global_continuous_event_ptr	t_continuous_event_ptr;
	typedef t_global_continuous_event_list	t_continuous_event_list;
	typedef t_global_placed_event			t_placed_event;
	typedef t_global_placed_event_ptr		t_placed_event_ptr;
	typedef t_global_placed_event_list		t_placed_event_list;

	t_owned_ptr<t_adventure_ai>		m_adventure_ai_ptr;
	t_artifact_set					m_allowed_artifacts;
	t_bool_array					m_allowed_heroes;
	t_skill_set						m_allowed_skills;
	t_spell_set						m_allowed_spells;
	t_army_list						m_armies;
	t_artifact_ai_importance_map	m_artifact_ai_importance_map; // Non-standard importance only. Does not include parchments & scrolls
	t_caravan_set					m_caravans;
	t_artifact_set					m_carry_in_artifacts;
	t_artifact_set					m_carry_out_artifacts;
	t_carryover_data_ptr			m_carry_in_data;
	t_carryover_data_ptr			m_carry_out_data;
    t_obelisk_flags                 m_completed_obelisk_flags;
	bool							m_cheater;
	int								m_current_player_number;
	bool							m_danger_marked;
	int								m_day;
	mutable t_default_hero_list		m_default_heroes;
	t_hero_list						m_defeated_heroes;
	t_scenario_cut_scene_info		m_epilogue_info;
	t_adventure_event_list			m_event_buffer;
	t_saved_game_header				m_event_header;
	t_adventure_event_playback		m_event_playback;
	unsigned int					m_event_tick;
	t_campaign_file_ref				m_file_ref;
	int								m_first_free_id;
	int								m_first_object_id;
    mutable t_ferry_group_id_map	m_ferries; // All magic ferries. Int value is ferry group id
	mutable t_ferry_group_vector	m_ferries_by_group; // m_ferries_by_group[group_id] is list of ferries in group 'group_id'
	mutable bool					m_ferry_groups_calculated;
	bool							m_game_over;
	t_ownable_garrisonable_adv_object_list	m_garrisons;
    t_gateway_vector_vector			m_gateways; // Indexed by gateway type
	t_adventure_global_id_factory	m_global_id_factory;
	t_adventure_global_id_map		m_global_id_map;
	bool							m_guards_can_move;
	bool							m_in_neutral_turn;
	bool							m_is_replay_map;
	int								m_last_object_id;
	int								m_player_number;
	std::string						m_loss_condition_string[k_active_player_color_count];
	t_adv_magi_eye_list				m_magi_eyes;
	t_terrain_map					m_map;
	t_boolean_variable_map			m_map_boolean_variables;
	t_deletion_marker_map			m_map_deletion_markers;
	t_hero_name_map					m_map_hero_name;
	int								m_map_number;
	t_numeric_variable_map			m_map_numeric_variables;
	int								m_map_random_seed;
	t_town_name_map					m_map_town_name;
	t_adventure_map_window* 		m_map_window;
	bool							m_multi_scenario;
	t_creature_type					m_next_month_creature; // Next "month of" event
    t_obelisk_list                  m_obelisks;
	t_level_map_point_2d            m_obelisk_artifact_position[k_obelisk_color_count];
	int			                    m_obelisk_count[k_obelisk_color_count];
	t_obelisk_data					m_obelisk_data[k_obelisk_color_count];
	t_obelisk_marker_list           m_obelisk_marker_list[k_obelisk_color_count];
    t_obelisk_flags                 m_obelisk_placed_treasure_flags;
	t_object_node_list				m_objects;
	t_spell_ai_importance_map		m_parchment_ai_importance_map;
	t_object_list					m_path_display;
	t_placed_event_list				m_placed_events;
	t_player_list					m_players;
	t_difficulty                    m_player_difficulty;
	t_creature_type					m_previous_month_creature; // Latest "month of" event
	t_scenario_cut_scene_info		m_prologue_info;
	bool									m_record_replay_events;
	t_adventure_object_cache_manager_ptr	m_replay_event_state_map;
	t_memory_buffer							m_replay_terrain_map;
	t_memory_buffer							m_replay_shroud_transition_map;
	t_respawn_point_list			m_respawn_point_list;
	t_owned_ptr<t_saved_combat>		m_saved_combat;
	t_adventure_object_ptr			m_selected_icon;
	t_shipyard_list					m_shipyards;
	t_shroud_transition_map_ptr		m_shroud_transition_maps[ k_active_player_color_count ];
	int								m_single_use_object_count;
	t_spell_ai_importance_map		m_scroll_ai_importance_map; // Non-standard importance only.
	int								m_spell_count[ k_spell_count ];
	bool							m_standard_victory_condition;
    t_adv_subterranean_gate_vector	m_subterranean_gates;
    t_teleporter_exit_vector_vector	m_teleporter_exits; // Indexed by teleporter type
	t_timed_event_list				m_timed_events;
	int								m_total_map_income;
	t_town_list						m_towns;
    int                             m_turn_duration_index;    
	t_triggerable_event_list		m_triggerable_events;
	t_continuous_event_list			m_continuous_events;
	t_artifact_set					m_used_artifacts;
	t_spell_set						m_used_parchments;
	t_bool_vector_vector			m_used_random_names; // Index is random name list index
	t_vertex_map					m_vertex_map;
	std::string						m_victory_condition_string[ k_active_player_color_count ];
	int								m_victory_timer;
    t_adv_whirlpool_vector			m_whirlpools;
	int								m_winning_team;
};									

// inlines for adventure map


inline bool t_adventure_map::is_cheater() const
{
	return m_cheater;
}

inline void t_adventure_map::set_cheater( bool arg )
{
	m_cheater = arg;
}

inline void t_adventure_map::add_obelisk_marker( t_obelisk_color marker_color, t_obelisk_marker const & marker )
{
	m_obelisk_marker_list[marker_color].push_back(marker);
}

inline int t_adventure_map::get_victory_timer() const
{
	return m_victory_timer;
}

inline void t_adventure_map::decrement_victory_timer()
{
	m_victory_timer--;
}

inline void t_adventure_map::set_winning_team( int team )
{
	m_winning_team = team;
	m_victory_timer = 3;
}

inline int t_adventure_map::get_winning_team() const
{
	return m_winning_team;
}

inline void t_adventure_map::float_object( int id )
{
	on_floating_object( id );
}

inline t_difficulty t_adventure_map::get_player_difficulty() const
{
    return m_player_difficulty;
}

inline t_campaign_file_ref const & t_adventure_map::get_file_ref() const
{
	return m_file_ref;
}

inline int t_adventure_map::get_map_number() const
{
	return m_map_number;
}
        
inline int t_adventure_map::get_turn_duration_index() const
{
    return m_turn_duration_index;
}

inline t_adventure_object& t_adventure_map::get_adv_object( t_object_id id )
{
	return *m_objects[id].object;
}

inline t_adventure_object const & t_adventure_map::get_adv_object( t_object_id id ) const
{
	return *m_objects[id].object;
}

inline t_adventure_tile const& t_adventure_map::get_adv_tile( t_level_map_point_2d const& point ) const
{
	return m_map.get( point );
}

inline t_adventure_tile& t_adventure_map::get_adv_tile( t_level_map_point_2d const& point )
{
	return m_map.get( point );
}

inline t_artifact_set const & t_adventure_map::get_allowed_artifacts() const
{
	return m_allowed_artifacts;
}

inline t_bool_array const & t_adventure_map::get_allowed_heroes() const
{
	return m_allowed_heroes;
}

inline t_skill_set const & t_adventure_map::get_allowed_skills() const
{
	return m_allowed_skills;
}

inline t_spell_set const & t_adventure_map::get_allowed_spells() const
{
	return m_allowed_spells;
}

inline t_army_list::iterator t_adventure_map::get_armies_begin()
{
	return m_armies.begin();
}

inline t_army_list::iterator t_adventure_map::get_armies_end()
{
	return m_armies.end();
}

inline t_caravan_set & t_adventure_map::get_caravans()
{
	return m_caravans;
}

inline t_caravan_set const & t_adventure_map::get_caravans() const
{
	return m_caravans;
}

inline t_adventure_object const & t_adventure_map::get_const_adv_object( t_object_id id ) const
{
	return *m_objects[id].object;
}

inline int t_adventure_map::get_day() const
{
	return m_day;
}

inline int t_adventure_map::get_total_income() const
{
	return m_total_map_income;
}

inline t_default_hero t_adventure_map::get_generic_hero( int portrait_id ) const
{
	return m_default_heroes.get_generic( portrait_id );
}

inline t_player& t_adventure_map::get_player() const
{
	return *m_players[m_player_number];
}

inline std::string const & t_adventure_map::get_loss_condition_string( t_player_color color ) const
{
	assert( (color > k_player_none) && (color < k_player_gray) );

	return m_loss_condition_string[color];
}

inline t_adv_magi_eye_list const &	t_adventure_map::get_magi_eyes() const
{
	return m_magi_eyes;
}

inline t_obelisk_marker_list const & t_adventure_map::get_obelisk_marker_list( t_obelisk_color obelisk_type ) const
{
	return m_obelisk_marker_list[obelisk_type];
}

inline t_obelisk_reward_list const & t_adventure_map::get_obelisk_reward_list( t_obelisk_color obelisk_type ) const
{
	return m_obelisk_data[ obelisk_type ].get_reward_list();
}

inline t_adventure_object * t_adventure_map::get_object_by_global_id( t_adventure_global_id id )
{
	if ( id == k_invalid_global_id )
		return NULL;

	t_adventure_global_id_map::iterator it = m_global_id_map.find( id );
	if ( it == m_global_id_map.end() )
		return NULL;
	else
		return it->second;
}

inline t_adventure_object const * t_adventure_map::get_object_by_global_id( t_adventure_global_id id ) const
{
	if ( id == k_invalid_global_id )
		return NULL;

	t_adventure_global_id_map::const_iterator it = m_global_id_map.find( id );
	if ( it == m_global_id_map.end() )
		return NULL;
	else
		return it->second;
}

inline int t_adventure_map::get_player_number() const
{
	return m_player_number;
}

inline t_map_size t_adventure_map::get_map_size_type() const
{
	int size = get_size();

	if (size <= k_small_map_size)
		return k_map_size_small;
	if (size <= k_medium_map_size)
		return k_map_size_medium;
	if (size <= k_large_map_size)
		return k_map_size_large;
	return k_map_size_extra_large;
}
	
inline t_adventure_global_id t_adventure_map::get_new_global_adventure_id( )
{
	return m_global_id_factory.get_new_id();
}

inline int t_adventure_map::get_new_single_use_id()
{
	return m_single_use_object_count++;
}

inline t_creature_type t_adventure_map::get_next_month_creature()
{
	return m_next_month_creature;
}

inline t_player_list const& t_adventure_map::get_players() const
{
	return m_players;
}

inline t_player& t_adventure_map::get_player( int id ) const
{
	assert( id < (int)m_players.size() );
	return *m_players[id];
}

inline int t_adventure_map::get_player_count() const
{
	return m_players.size();
}

inline t_player* t_adventure_map::get_player( t_player_color color ) const
{
	int number = get_player_number( color );
	if (number < 0)
		return 0;
	return m_players[number].get();
}

inline t_creature_type t_adventure_map::get_previous_month_creature()
{
	return m_previous_month_creature;
}

inline int t_adventure_map::get_required_obelisks( t_obelisk_color obelisk_type ) const
{
	return minimum(m_obelisk_count[ obelisk_type ], int( m_obelisk_data[ obelisk_type ].get_needed_count() ) );
}

inline t_saved_combat* t_adventure_map::get_saved_combat()
{
	return m_saved_combat.get();
}

inline std::vector<t_default_hero> t_adventure_map::get_unused_heroes( t_hero_class hero_class, 
																	   bool male ) const
{
	return m_default_heroes.get_unused( hero_class, male );
}

inline int t_adventure_map::get_town_count() const
{
    return m_towns.size();
}

inline t_adventure_map::t_town_list::const_iterator t_adventure_map::get_towns_begin() const
{
	return m_towns.begin();
}

inline t_adventure_map::t_town_list::const_iterator t_adventure_map::get_towns_end() const
{
	return m_towns.end();
}

 inline t_ownable_garrisonable_adv_object_list::iterator t_adventure_map::get_garrisons_begin()
{
	return m_garrisons.begin();
}

inline t_ownable_garrisonable_adv_object_list::iterator t_adventure_map::get_garrisons_end()
{
	return m_garrisons.end();
}

inline t_adventure_map::t_town_list::iterator t_adventure_map::get_towns_begin()
{
	return m_towns.begin();
}

inline t_adventure_map::t_town_list::iterator t_adventure_map::get_towns_end()
{
	return m_towns.end();
}

inline std::string const & t_adventure_map::get_victory_condition_string( t_player_color color ) const
{
	assert( (color > k_player_none) && (color < k_player_gray) );

	return m_victory_condition_string[ color ];
}

inline bool t_adventure_map::is_blocked( t_adv_map_point const& point ) const
{
	return m_map.get( point ).is_blocked( point.on_bridge );
}


inline bool t_adventure_map::is_multi_scenario() const
{
	return m_multi_scenario;
}

inline bool t_adventure_map::get_standard_victory_condition() const
{
	return m_standard_victory_condition;
}

inline bool t_adventure_map::guards_can_move() const
{
	return m_guards_can_move;
}

inline bool t_adventure_map::is_hero_portrait_used( int portrait_id ) const
{
	return m_default_heroes.is_portrait_used( portrait_id );
}

// check if an army can be placed in a tile
inline bool	t_adventure_map::is_open( t_adv_map_point const& point, t_creature_array const& army ) const
{
	t_adventure_tile const& tile = get_adv_tile( point );

	// use "place army search" so all points, including those
	// with unseen armies, block this army.
	return !tile.blocks_army( army, *this, point.on_bridge, k_path_search_place_army );
}

inline bool t_adventure_map::is_trigger( t_adv_map_point point )
{
	return get_adv_tile( point ).is_trigger( point.on_bridge );
}

inline void t_adventure_map::record_hero_usage( int biography_id, int portrait_id )
{
	m_default_heroes.use( biography_id, portrait_id );
}

inline void t_adventure_map::free_hero_usage( int biography_id, int portrait_id )
{
	m_default_heroes.discard( biography_id, portrait_id );
}

inline t_adventure_tile const& t_adventure_map::operator[]( t_level_map_point_2d point ) const
{
	return m_map.get( point );
}

inline void t_adventure_map::sink_object( int id )
{
	on_object_sunk( id );
}

inline void t_adventure_map::set_day( int arg )
{
	m_day = arg;
}

inline void t_adventure_map::set_is_replay_map( bool arg )
{
	m_is_replay_map = arg;
}

inline void t_adventure_map::set_player( int id )
{
	m_player_number = id;
}

inline void t_adventure_map::set_loss_condition_string( t_player_color color, std::string const & loss_condition )
{
	assert( (color > k_player_none) && (color < k_player_gray) );

	m_loss_condition_string[ color ] = loss_condition;
}

inline void t_adventure_map::set_player_difficulty( t_difficulty difficulty )
{
	if( difficulty < k_difficulty_easy )
		difficulty = k_difficulty_easy;
	else
	if( difficulty > k_difficulty_impossible )
		difficulty = k_difficulty_impossible;
	m_player_difficulty = difficulty;
}

inline void t_adventure_map::set_standard_victory_condition( bool condition )
{
	m_standard_victory_condition = condition;
}

inline void t_adventure_map::set_victory_condition_string( t_player_color color, std::string const & victory_condition )
{
	m_victory_condition_string[ color ] = victory_condition;
}

inline void t_adventure_map::use_artifact( t_artifact_type artifact )
{
	m_used_artifacts.set( artifact );
}

inline void t_adventure_map::set_game_over( bool over )
{
	m_game_over = over;
}

inline t_scenario_cut_scene_info const & t_adventure_map::get_epilogue_info() const
{
	return m_epilogue_info;
}

inline t_scenario_cut_scene_info const & t_adventure_map::get_prologue_info() const
{
	return m_prologue_info;
}

inline t_artifact_set const & t_adventure_map::get_carry_in_artifacts() const
{
	return m_carry_in_artifacts;
}

inline t_artifact_set const & t_adventure_map::get_carry_out_artifacts() const
{
	return m_carry_out_artifacts;
}

inline void t_adventure_map::increment_spell_count( t_spell spell )
{
	m_spell_count[spell]++;
}

inline void t_adventure_map::reset_danger() 
{
	m_danger_marked = false;
}

t_map_rect_2d get_visibility_rect( t_map_point_2d const &	center, // In half cell coordinates
								   int						radius,
							       int						map_size );


#endif
